package com.suncky.frame.widget.dropwindow;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;

import androidx.annotation.Nullable;

import com.suncky.frame.R;
import com.suncky.frame.utils.LogUtils;

import java.util.List;

/**
 * 下拉列表选项弹框
 */
public abstract class DropPopup<T> extends PopupWindow {
    private final Context context;
    private OnItemSelectListener<T> onItemSelectListener;
    private List<T> items;
    private int itemGravity = Gravity.START;
    private int normalItemColor = Color.rgb(102, 102, 102);
    private int selectedItemColor = Color.rgb(57, 154, 251);
    private float itemTextSize = 0;
    private int fixedWidth = WindowManager.LayoutParams.WRAP_CONTENT;//固定的宽度
    private int calculatedWidth = 0;
    private int minWidth = 0;
    private int itemLayoutId;
    private PopupAdapter adapter;

    public DropPopup(Context context) {
        this(context, null);
    }


    public DropPopup(Context context, List<T> items){
        this(context, items,R.layout.layout_drop_popup_item);
    }

    public DropPopup(Context context, List<T> items,int itemLayoutId) {
        this(context, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, items,itemLayoutId);
    }

    public DropPopup(Context context, int width, int height, List<T> items) {
        this(context, width, height, items, R.layout.layout_drop_popup_item);
    }

    public DropPopup(Context context, int width, int height, List<T> items, int itemLayoutId) {
        this.context = context;
        this.items = items;
        this.itemLayoutId = itemLayoutId;
        setHeight(height);
        setWidth(width);
        initPopup();
    }

    /**
     * 设置宽度,当设置的值大于0时,控件的宽度是固定的,否则宽度自适应内容
     * @param width the popup width in pixels or a layout constant
     */
    @Override
    public void setWidth(int width) {
        this.fixedWidth = width;
        //父类构造函数会调用setWidth方法,此时context未初始化
        if (context != null) {
            updateWidth();
        }
    }

    /**
     * 设置控件的最小宽度。当控件的宽度固定时(fixedWidth>0),最小宽度无效
     * @param minWidth 最小宽度
     */
    public void setMinWidth(int minWidth) {
        this.minWidth = minWidth;
        if (fixedWidth > 0) {
            return;
        }
        super.setWidth(Math.max(calculatedWidth, minWidth));
    }

    /**
     * 设置下拉列表item的布局id.
     * 请将显示选项内容的TextView的id设为android.R.id.text1
     * @param layoutId 布局id
     */
    public void setItemLayoutId(int layoutId) {
        if (layoutId == this.itemLayoutId) {
            return;
        }
        this.itemLayoutId = layoutId;
        updateWidth();
    }

    private void updateWidth() {
        if (fixedWidth > 0) {
            super.setWidth(fixedWidth);
        }else {
            calculatedWidth = calculateWidth();
            super.setWidth(calculatedWidth);
        }
    }

    /**
     * 设置未选中的item颜色
     * @param color
     */
    public void setNormalItemColor(int color) {
        this.normalItemColor = color;
    }

    /**
     * 设置选中的item颜色
     * @param color
     */
    public void setSelectedItemColor(int color) {
        this.selectedItemColor = color;
    }

    /**
     * 设置选项
     * @param items
     */
    public void setItems(List<T> items) {
        this.items = items;
        updateWidth();
    }

    /**
     * 设置item对齐方式
     * @param itemGravity 对齐方式 {@link Gravity}
     */
    public void setItemGravity(int itemGravity) {
        this.itemGravity = itemGravity;
    }

    /**
     * 设置item字体大小
     * @param itemTextSize item字体像素大小
     */
    public void setItemTextSize(float itemTextSize) {
        this.itemTextSize = itemTextSize;
    }

    public void setBackgroundRes(int backgroundRes) {
        setBackgroundDrawable(context.getResources().getDrawable(backgroundRes));
    }

    /**
     * 设置选中事件监听
     * @param onItemSelectListener
     */
    public void setOnItemSelectListener(OnItemSelectListener<T> onItemSelectListener) {
        this.onItemSelectListener = onItemSelectListener;
    }


    /**
     * 设置popup的样式
     */
    private void initPopup() {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View menuView = inflater.inflate(R.layout.layout_drop_popup, null);
        ListView itemLv = menuView.findViewById(R.id.popup_lv);
        adapter = new PopupAdapter(context);
        itemLv.setAdapter(adapter);
        itemLv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                select(position);
                if (onItemSelectListener != null) {
                    onItemSelectListener.onItemSelect(position, items.get(position));
                }
                dismiss();
            }
        });
        // 设置AccessoryPopup的view
        this.setContentView(menuView);
        // 设置AccessoryPopup弹出窗体可点击
        this.setFocusable(true);
        // 设置AccessoryPopup弹出窗体的动画效果
        this.setAnimationStyle(com.suncky.frame.R.style.fade_window_animation);

        // 实例化一个ColorDrawable颜色为半透明
        ColorDrawable dw = new ColorDrawable(0x33000000);
        // 设置PopupWindow弹出窗体的背景
        this.setBackgroundDrawable(dw);
    }

    /**
     * 计算弹窗需要的宽度
     */
    private int calculateWidth() {
        if (itemLayoutId <= 0) {
            itemLayoutId = R.layout.layout_drop_popup_item;
        }
        View view = LayoutInflater.from(context).inflate(itemLayoutId, null);
        TextView textView = view.findViewById(android.R.id.text1);
        Paint paint = textView.getPaint();
        int padding = view.getPaddingStart() + view.getPaddingEnd() + textView.getPaddingStart() + textView.getPaddingEnd();
        int width = padding;
        if (items == null || items.size() == 0) {
            return Math.max(width, minWidth);
        }
        for (int i = 0; i < items.size(); ++i) {
            String text = getItemText(items.get(i), i);
            if (TextUtils.isEmpty(text)) {
                continue;
            }
            int textWidth = (int) (paint.measureText(text) + text.length() + padding);
            if (width < textWidth) {
                width = textWidth;
            }
        }
        return Math.max(width, minWidth);
    }

    /**
     * 选中选项
     * @param item 选项
     */
    public void select(T item){
        if (adapter != null && items != null) {
            adapter.setPosition(items.indexOf(item));
        }
    }

    /**
     * 选中位置
     * @param position 位置
     */
    public void select(int position){
        if (adapter != null) {
            adapter.setPosition(position);
        }
    }

    /**
     * 获取选中的位置
     * @return
     */
    public int getPosition(){
        if (adapter != null) {
            return adapter.getPosition();
        }
        return 0;
    }

    /**
     * 获取已选的选项
     * @return 选择的选项
     */
    public T getSelectedItem() {
        if (adapter != null) {
            return adapter.getItem(getPosition());
        }
        return null;
    }

    /**
     * 显示弹框
     * @param anchor
     */
    public void show(View anchor) {
        super.showAsDropDown(anchor);
    }

    @Nullable
    public abstract String getItemText(T item, int position);

    public interface OnItemSelectListener<T>{
        void onItemSelect(int position, T item);
    }

    public  class PopupAdapter extends BaseAdapter {
        private final LayoutInflater inflater;
        private int mPosition = 0;

        public PopupAdapter(Context context) {
            super();
            inflater = LayoutInflater.from(context);
        }

        public void setPosition(int position) {
            this.mPosition = position;
            notifyDataSetChanged();
        }

        public int getPosition() {
            return mPosition;
        }

        @Override
        public int getCount() {
            if (items == null) {
                return 0;
            }
            return items.size();
        }

        @Override
        public T getItem(int position) {
            if (items == null) {
                return null;
            }
            if (position < 0 || position >= items.size()) {
                return null;
            }
            return items.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            LogUtils.i("getView invoked position=" + position);
            PopupHolder holder;
            if (convertView == null) {
                holder = new PopupHolder();
                convertView = inflater.inflate(itemLayoutId, null);
                holder.itemTv = convertView
                        .findViewById(android.R.id.text1);
                holder.itemTv.setGravity(itemGravity);
                if (itemTextSize > 0) {
                    holder.itemTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, itemTextSize);
                }
                convertView.setTag(holder);
            } else {
                holder = (PopupHolder) convertView.getTag();
            }
            holder.itemTv.setText(getItemText(getItem(position),position));
            if (mPosition == position) {
                holder.itemTv.setTextColor(selectedItemColor);
            } else {
                holder.itemTv.setTextColor(normalItemColor);
            }
            return convertView;
        }

        private class PopupHolder {
            TextView itemTv;
        }
    }
}
